home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / Amiga-E / E_v3.2a_extras / PdSrc / Pyth2.e < prev    next >
Text File  |  1992-09-02  |  6KB  |  214 lines

  1. /*
  2. **    This is the E version of the 'Tree of Pythagoras'.
  3. **    Written by Raymond Hoving, Waardgracht 30, 2312 RP Leiden,
  4. **    The Netherlands.
  5. **    E-mail address: hoving@stpc.wi.leidenuniv.nl
  6. **    Requires Kickstart V3.0+ and reqtools.library V38+
  7. **    Creation date: Sun Jul 17 17:30:07 1994, Version: 2.0
  8. */
  9.  
  10. OPT    REG=5,OSVERSION=39    /* Kickstart 3.0+ only. */
  11.  
  12. MODULE    'intuition/intuition', 'intuition/screens', 'utility/tagitem',
  13.     'reqtools', 'exec/ports', 'exec/libraries',
  14.     'libraries/reqtools', 'graphics/modeid', 'graphics/text'
  15.  
  16. DEF    pythscreen=NIL : PTR TO screen,
  17.     pythwindow=NIL : PTR TO window,
  18.     pythidcmp=NIL : PTR TO mp,
  19.     screenmodereq=NIL : PTR TO rtscreenmoderequester,
  20.     scrwidth, scrheight, fontheight,
  21.     winxsize, winysize, xbase, ybase, mbase,
  22.     depth=1, mdepth=10,
  23.     time0, time1
  24.  
  25. CONST   BORDERSIZE = 4
  26.             
  27. ENUM    MSG_READY, MSG_ABORT, ERROR_REQTLIB, ERROR_SCREEN,
  28.     ERROR_WINDOW, ERROR_OOM
  29.  
  30. PROC     pythcleanup(errornumber)
  31.  
  32.     /* This procedure will deallocate all objects that were succesfully
  33.     ** allocated. When an error occured, this will be told to the user.
  34.     */
  35.  
  36.     IF pythwindow<>NIL THEN CloseWindow(pythwindow)
  37.     IF pythscreen<>NIL THEN CloseScreen(pythscreen)
  38.     IF screenmodereq<>NIL THEN RtFreeRequest(screenmodereq) 
  39.     IF reqtoolsbase<>NIL THEN CloseLibrary(reqtoolsbase)
  40.     SELECT    errornumber
  41.         CASE ERROR_OOM
  42.             WriteF('ERROR: Out of memory.\n')
  43.         CASE ERROR_REQTLIB
  44.             WriteF('ERROR: Couldn\at open reqtools.library.\n')
  45.         CASE ERROR_SCREEN
  46.             WriteF('ERROR: Couldn\at open new screen.\n')
  47.         CASE ERROR_WINDOW
  48.             WriteF('ERROR: Couldn\at open new window.\n')
  49.         CASE MSG_ABORT
  50.             WriteF('Drawing cancelled.\n')
  51.         CASE MSG_READY
  52.             WriteF('I just drew \d little house\s!\n',
  53.                 Shl(1,mdepth)-1,
  54.                 IF mdepth=1 THEN '' ELSE 's')
  55.     ENDSELECT
  56.     CleanUp(errornumber)    /* Call the standard E finalizer. */
  57. ENDPROC
  58.  
  59. PROC    pythtree(a1,a2,b1,b2)
  60.  
  61.     /* This (recursively called) procedure will do the actual
  62.     ** drawing of the tree.
  63.     */
  64.  
  65.     DEF c1,c2,d1,d2,e1,e2,ci1,ci2,di1,di2
  66.     IF GetMsg(pythidcmp)<>NIL THEN pythcleanup(MSG_ABORT)
  67.     IF depth<=mdepth        /* Check if we aren't too deep. */
  68.       INC depth            /* This depth is still allowed. */
  69.       SetAPen(stdrast,depth)    /* Drawing color depends on recursion depth. */
  70.       c1 := !a1-a2+b2 ; ci1 := !c1!
  71.       c2 := !a1+a2-b1 ; ci2 := !c2!
  72.       d1 := !b1+b2-a2 ; di1 := !d1!
  73.       d2 := !a1-b1+b2 ; di2 := !d2!    /* Calculate all       */
  74.       e1 := !0.5 * (!c1-c2+d1+d2)    /* needed coordinates. */
  75.       e2 := !0.5 * (!c1+c2-d1+d2)
  76.       /*
  77.       **         e      Note the use of ! between () in the calculations of e1 and
  78.       **        /\      e2. We use some extra LONG's to minimize convertion
  79.       **       /  \     overhead.
  80.       **     c+----+d   The coordinates of c,d and e are calculated from the
  81.       **      |    |    coordinates of a and b. Lineair Algebra is great fun!
  82.       **      |    |
  83.       **     a+----+b
  84.       */
  85.       Move(stdrast,ci1,ci2)
  86.       Draw(stdrast,!a1!,!a2!)
  87.       Draw(stdrast,!b1!,!b2!)
  88.       Draw(stdrast,di1,di2)
  89.       Draw(stdrast,ci1,ci2)
  90.       Draw(stdrast,!e1!,!e2!)
  91.       Draw(stdrast,di1,di2)        /* Draw the little house.  */
  92.       IF Rnd(2) = 0         /* Makes the growing a bit */
  93.         pythtree(c1,c2,e1,e2)    /* more interesting.       */
  94.         pythtree(e1,e2,d1,d2)
  95.       ELSE
  96.         pythtree(e1,e2,d1,d2)
  97.         pythtree(c1,c2,e1,e2)
  98.       ENDIF
  99.       DEC depth            /* Ready with this branch. */
  100.     ENDIF
  101. ENDPROC
  102.  
  103. PROC    main()
  104.  
  105.     DEF a1,a2,b1,b2
  106.  
  107.     /* Open reqtools.library and allocate memory for requester structure.
  108.         */
  109.  
  110.     IF (reqtoolsbase := OpenLibrary('reqtools.library',38)) = NIL THEN
  111.       pythcleanup(ERROR_REQTLIB)
  112.     
  113.     IF (screenmodereq := RtAllocRequestA(RT_SCREENMODEREQ,NIL)) = NIL THEN
  114.       pythcleanup(ERROR_OOM)    
  115.     
  116.     /* Let the user decide which screenmode he/she wishes. Note that
  117.     ** the tree looks best on a screen with approximately the same
  118.     ** number of pixels in both directions, like 640x512.
  119.     */
  120.  
  121.     IF RtScreenModeRequestA(screenmodereq,'Tree of Pythagoras', [
  122.       RTSC_FLAGS,SCREQF_OVERSCANGAD OR SCREQF_AUTOSCROLLGAD OR SCREQF_SIZEGADS,
  123.       RTSC_MINWIDTH,100,
  124.       RTSC_MINHEIGHT,100,
  125.           TAG_DONE]) = FALSE THEN pythcleanup(MSG_ABORT)
  126.  
  127.     /* Then ask the maximum depth of recursion.
  128.     */
  129.  
  130.     IF (RtGetLongA({mdepth},'Tree of Pythagoras',NIL, [
  131.       RTGL_MIN,1,
  132.       RTGL_MAX,14,
  133.       RTGL_TEXTFMT,'Enter maximum depth of the tree:',
  134.       RT_WINDOW,pythwindow,
  135.       TAG_DONE])) = FALSE THEN pythcleanup(MSG_ABORT)
  136.  
  137.     /* Get relevant data from the screenmode structure.
  138.     */    
  139.  
  140.     scrwidth := screenmodereq.displaywidth
  141.     scrheight := screenmodereq.displayheight
  142.  
  143.     /* Open the screen the user decided to want.
  144.     */
  145.  
  146.     IF (pythscreen := OpenScreenTagList(NIL, [
  147.       SA_DEPTH,4,
  148.       SA_TYPE,CUSTOMSCREEN,
  149.       SA_DISPLAYID,screenmodereq.displayid,
  150.       SA_WIDTH,scrwidth,
  151.       SA_HEIGHT,scrheight,
  152.       SA_TITLE,'Screen of Pythagoras',
  153.       TAG_DONE])) = NIL THEN pythcleanup(ERROR_SCREEN)
  154.  
  155.     /* Now open a screen filling window on the sceen that was just opened.
  156.     */
  157.  
  158.     IF (pythwindow:=OpenWindowTagList(NIL, [
  159.       WA_WIDTH,scrwidth,
  160.       WA_HEIGHT,scrheight,
  161.       WA_IDCMP,IDCMP_CLOSEWINDOW,
  162.       WA_FLAGS,WFLG_CLOSEGADGET OR WFLG_ACTIVATE,
  163.       WA_TITLE,'Tree of Pythagoras by Raymond Hoving',
  164.       WA_CUSTOMSCREEN,pythscreen,
  165.       TAG_DONE])) = NIL THEN pythcleanup(ERROR_WINDOW)
  166.  
  167.     /* Get some useful data from the window structure.
  168.     */
  169.  
  170.     stdrast := pythwindow.rport
  171.     pythidcmp := pythwindow.userport
  172.     fontheight := pythwindow.ifont::textfont.ysize
  173.  
  174.     /* Set the palette for this screen (brown to green).
  175.     */
  176.  
  177.     LoadRGB4(ViewPortAddress(pythwindow), [
  178.       $000,$89a,$640,$752,$762,$771,$781,$680,$580,$080,
  179.       $090,$0a0,$0b0,$0c0,$0d0,$0e0] : INT, 16)
  180.  
  181.  
  182.     /* Build a 'real random' seed from the current time
  183.     */
  184.  
  185.     CurrentTime({time0},{time1})
  186.     Rnd(-Abs(Eor(time0,time1)))
  187.  
  188.     /* Now calculate how big the tree can be on the selected screen.
  189.     */
  190.  
  191.     winxsize := scrwidth - (2 * BORDERSIZE)
  192.     winysize := scrheight - (6 * BORDERSIZE + fontheight)
  193.     xbase := winxsize! / 12.2    /* Divider found by trial and error. */
  194.     ybase := winysize! / 8.0    /* This one as well.                 */
  195.     IF !xbase < ybase THEN mbase := xbase ELSE mbase := ybase
  196.     a1 := scrwidth! / 2.0 - mbase
  197.     b1 := scrwidth! / 2.0 + mbase
  198.     a2 := scrheight - (4 * BORDERSIZE)!
  199.     b2 := a2
  200.     
  201.     /* Set the busy pointer and start drawing.
  202.     */
  203.  
  204.     SetWindowPointerA(pythwindow,[WA_BUSYPOINTER,TRUE,TAG_DONE])        
  205.     pythtree(a1,a2,b1,b2)
  206.     SetWindowPointerA(pythwindow,TAG_DONE)
  207.  
  208.     /* Ready! Wait for the user to close the window.
  209.     */
  210.     
  211.     WaitPort(pythidcmp)
  212.     pythcleanup(MSG_READY)
  213. ENDPROC
  214.